﻿#region Using Statements
using System;
using System.Linq;
using System.IO;
using System.Collections.Generic;
using System.Collections;
using System.Collections.Specialized;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using sqengine.Engine.Common;
using System.Threading;
using sqengine.Components;
using System.Reflection;
using System.Security.Cryptography;
using System.Runtime.InteropServices;

#endregion

namespace sqengine
{
    #region Console Help Attribute
    public enum ConsoleCommandType
    {
        Normal,
        Cheat,
        Debug,
        Experimental

    }

    public class ConsoleHelpAttribute : Attribute
    {
        public ConsoleHelpAttribute(string command, string help, ConsoleCommandType commandtype)
        {
            this.command = command;
            this.help = help;
            this.commandtype = commandtype;
        }
        protected string command;
        protected string help;
        protected ConsoleCommandType commandtype;

        public string Command
        {
            get
            {
                return this.command;

            }
        }

        public string Help
        {
            get
            {
                return this.help;

            }
        }

        public ConsoleCommandType CommandType
        {
            get
            {
                return this.commandtype;
            }
        }

    }
    #endregion

    class ConsoleCommands
    {
        SqConsole _cons;
        TwitterAPI twitter;
        NetworkAPI networkapi;

        SortedDictionary<string, string> _sorted;
        Dictionary<string, string> _dict = new Dictionary<string, string>();

        public ConsoleCommands(SqConsole cons)
        {
            _cons = cons;

        }
        Dictionary<string, string> _tmpdic = new Dictionary<string, string>();


        [ConsoleHelp("echo", "-- Write to console", ConsoleCommandType.Normal)]
        public string echo(Game game, string text)
        {
            return ParseCmdString(game, ParseVarString(game, text));

        }

        [ConsoleHelp("version", "-- Show current version", ConsoleCommandType.Normal)]
        public string version(Game game, string command)
        {

            return SqEngine.SqEngineInfo._name + " " + SqEngine.SqEngineInfo._version + "\n" + SqEngine.SqEngineInfo._author + " " + SqEngine.SqEngineInfo._website;
        }

        [ConsoleHelp("quit", "-- Quit game", ConsoleCommandType.Normal)]
        public string quit(Game game, string text)
        {
            game.Exit();

            return "";
        }

        [ConsoleHelp("exit", "-- Quit game", ConsoleCommandType.Normal)]
        public string exit(Game game, string text)
        {

            quit(game, "");
            return "";
        }

        [ConsoleHelp("settitle", "-- Set title to parameter %s", ConsoleCommandType.Normal)]
        public string settitle(Game game, string text)
        {
            if (text != "")
                game.Window.Title = text;

            return "Title set";
        }

        [ConsoleHelp("getcomponents", "-- Get all active components", ConsoleCommandType.Normal)]
        public string getcomponents(Game game, string command)
        {
            string comps = "";
            for (int i = 0; i < game.Components.Count; i++)
            {
                if (game.Components[i] != null)
                    comps += game.Components[i].ToString() + "\n";

            }

            return comps + "\nTotal components: " + game.Components.Count.ToString();

        }

        [ConsoleHelp("gettitle", "-- Get title of Window", ConsoleCommandType.Normal)]
        public string gettitle(Game game, string command)
        {
            return game.Window.Title;
        }

        [ConsoleHelp("mapinfo", "-- Get information of current map", ConsoleCommandType.Normal)]
        public string mapinfo(Game game, string command)
        {
            MapInfo mapinfo = ((sqengine)game).GetCurrentMapInfo;

            if (mapinfo != null)
            {
                return mapinfo.MapName + "\nAuthor: " + mapinfo.Author + "\nDescription: " + mapinfo.Description + "\nObjects count: " + mapinfo.ObjectsCount.ToString() + "\nBots counts: " + mapinfo.BotsCount.ToString();
            }
            else
            {
                return "No map loaded!";
            }

        }

        [ConsoleHelp("loadmap", "-- Load map in game: Syntax: loadmap c:\\path\\path.sqm", ConsoleCommandType.Normal)]
        public string loadmap(Game game, string command)
        {

            if (System.IO.File.Exists(command))
            {
                ((sqengine)game).LoadMap(command);
                return "Loaded!";

            }
            else
            {
                return "Map file " + command + " does not exist!";

            }

        }

        [ConsoleHelp("mediaplayer_populatemp3", "-- Populate MP3 Playlist: Syntax: populatemp3 c:/path/mp3/", ConsoleCommandType.Normal)]
        public string mediaplayer_populatemp3(Game game, string command)
        {
            command = command.Replace('/', '\\');

            if (System.IO.Directory.Exists(command))
            {
                ((sqengine)game).MediaPlayerPopulateMP3(command);
                return "Loading...";
            }
            else
            {
                return String.Format("Directory {0} not found!", command);
            }

        }

        [ConsoleHelp("mediaplayer_play", "-- Play MediaPlayer ", ConsoleCommandType.Normal)]
        public string mediaplayer_play(Game game, string command)
        {

            ((sqengine)game).MediaPlayerPlay();
            return "MediaPlayer play";
        }

        [ConsoleHelp("mediaplayer_stop", "-- Stop MediaPlayer ", ConsoleCommandType.Normal)]
        public string mediaplayer_stop(Game game, string command)
        {

            ((sqengine)game).MediaPlayerStop();
            return "MediaPlayer stopped";
        }

        [ConsoleHelp("mediaplayer_next", "-- Next MediaPlayer ", ConsoleCommandType.Normal)]
        public string mediaplayer_next(Game game, string command)
        {

            ((sqengine)game).MediaPlayerNext();
            return "MediaPlayer next song";
        }

        [ConsoleHelp("mediaplayer_back", "-- Back MediaPlayer ", ConsoleCommandType.Normal)]
        public string mediaplayer_back(Game game, string command)
        {

            ((sqengine)game).MediaPlayerBack();
            return "MediaPlayer back song";
        }

        [ConsoleHelp("mediaplayer_enablerandom", "-- Enable MediaPlayer random mode: Syntax 0=false 1=true", ConsoleCommandType.Normal)]
        public string mediaplayer_enablerandom(Game game, string command)
        {
            bool en = false;
            if (command == "1")
                en = true;
            else
                en = false;
            ((sqengine)game).MediaPlayerEnableRandom(en);

            return String.Format("MediaPlayer Random enabled: {0}", en);
        }

        [ConsoleHelp("set", "-- Set ingame variable: Syntax set debug_mode 1", ConsoleCommandType.Normal)]
        public string set(Game game, string command)
        {
            if (command != "")
            {
                string var = command.Split(' ')[0];
                string value = command.Split(' ')[1];


                ((sqengine)game).ConsoleSetVar(var, value);

                return string.Format("{0} = {1}", var, value);
            }
            else
            {
                return string.Format("Variable cannot be empty: Syntax set debug_mode 1");

            }
        }

        [ConsoleHelp("get", "-- Get ingame variable: Syntax get debug_mode", ConsoleCommandType.Normal)]
        public string get(Game game, string command)
        {

            if (command != "")
            {

                if (((sqengine)game).ConsoleGetVar(command) != "")
                {
                    string gamevar = ((sqengine)game).ConsoleGetVar(command);

                    if (gamevar.Contains("password:"))
                    {
                        return "<PASSWORD>";
                    }
                    else
                    {
                        return gamevar;
                    }
                }

                else
                    return string.Format("Variable {0} not found", command);
            }
            else
            {
                string vars_result = "Game variables:\n";


                foreach (DictionaryEntry kvp in ((sqengine)game).GetInGameVars)
                {
                    string val = "";

                    if (kvp.Value.ToString().StartsWith("password:"))
                        val = "<PASSWORD>";
                    else
                        val = kvp.Value.ToString();

                    vars_result += string.Format("{0} = {1}\n", kvp.Key, val);
                }

                return vars_result;


            }

        }

        [ConsoleHelp("save_vars", "-- Save game variables in memory from file: Syntax: save_vars c:\\text.vars", ConsoleCommandType.Normal)]
        public string save_vars(Game game, string command)
        {
            SaveManager save_man = new SaveManager();
            GameVars gv = new GameVars();
            HybridDictionary tmpdict = new HybridDictionary();

            foreach (DictionaryEntry de in ((sqengine)game).GetInGameVars)
            {
                if (de.Value.ToString().Contains("password:"))
                {

                    string pwd = de.Value.ToString().Remove(0, 9);
                    pwd = Functions.base64Encode(pwd);
                    pwd = "password:" + pwd;

                    tmpdict.Add(de.Key, pwd);
                }
                else
                {
                    tmpdict.Add(de.Key, de.Value);
                }

            }

            gv.Vars = tmpdict;
            tmpdict = null;


            save_man.SaveGameVars(command, gv);

            save_man = null;
            gv = null;

            return string.Format("Variables saved to {0}", command);

        }

        [ConsoleHelp("load_vars", "-- Load game variables in memory from file: Syntax: load_vars c:\\text.vars {null for overwrite current vars | 1 add}", ConsoleCommandType.Normal)]
        public string load_vars(Game game, string command)
        {

            SaveManager save_man = new SaveManager();
            GameVars gv = new GameVars();
            HybridDictionary tmpdict = new HybridDictionary();
            bool overwrite = true;
            string filename = "";
            if (command.Split(' ').Length == 2)
            {
                if (command.Split(' ')[1] == "1")
                    overwrite = false;


                filename = command.Split(' ')[0];
            }
            else
            {
                filename = command;
            }




            if (File.Exists(filename))
            {

                gv = save_man.LoadGameVars(filename);

                foreach (DictionaryEntry de in gv.Vars)
                {
                    if (de.Value.ToString().StartsWith("password:"))
                    {
                        string pwd = de.Value.ToString().Remove(0, 9);
                        pwd = Functions.base64Decode(pwd);
                        pwd = "password:" + pwd;
                        tmpdict.Add(de.Key, pwd);
                    }
                    else
                    {
                        tmpdict.Add(de.Key, de.Value);
                    }

                }

                if (overwrite)
                {
                    ((sqengine)game).GetInGameVars.Clear();
                    ((sqengine)game).GetInGameVars = tmpdict;
                }
                else
                {
                    foreach (DictionaryEntry de in tmpdict)
                    {
                        if (((sqengine)game).GetInGameVars[de.Key] == null)
                            ((sqengine)game).GetInGameVars.Add(de.Key, de.Value);

                    }

                }
                return string.Format("{0} variables loaded ", gv.Vars.Count);
            }
            else
            {
                return string.Format("Error: {0} not found", command);
            }
        }

        [ConsoleHelp("help", "-- Show help of %s command or if input is empty show all commands", ConsoleCommandType.Normal)]
        public string help(Game game, string command)
        {
            return GetCommandHelp(command);
        }

        [ConsoleHelp("save_script", "-- Save current script to file %s: Syntax save_script c:\\script.sqs", ConsoleCommandType.Normal)]
        public string save_script(Game game, string command)
        {
            List<string> _history = ((sqengine)game).Console.GetHistory;

            StreamWriter stw = new StreamWriter(command);

            foreach (string itm in _history)
            {
                stw.WriteLine(itm);
            }

            stw.Close();

            return string.Format("Script saved {0}", command);

        }

        [ConsoleHelp("cat", "-- display file: Syntax cat c:\\script.sqs", ConsoleCommandType.Normal)]
        public string cat(Game game, string command)
        {
            int line = 0;
            string res = "";
            if (File.Exists(command))
            {
                StreamReader smr = new StreamReader(command);
                string script = smr.ReadToEnd();
                script = script.Replace('\r', ' ');

                res += string.Format("Displaying script {0}\n", command);

                foreach (string itm in script.Split('\n'))
                {
                    line++;
                    res += string.Format("{0}> {1}\n", line, itm.Trim());
                }

                return res;


            }
            else
            {
                return string.Format("File {0} don't exist", command);
            }

        }

        [ConsoleHelp("load_script", "-- Load script from file %s: Syntax load_script c:\\script.sqs", ConsoleCommandType.Normal)]
        public string load_script(Game game, string command)
        {
            int linecount = 0;
            if (File.Exists(command))
            {
                StreamReader streamReader = new StreamReader(command);
                string script = streamReader.ReadToEnd();
                streamReader.Close();
                streamReader.Dispose();

                script = script.Replace('\r', ' ');

                foreach (string line in script.Split('\n'))
                {
                    linecount++;
                    if (!line.StartsWith("#") && (line != " "))
                    {
                        string result = ((sqengine)game).Console.ExecCommand(line.Trim());

                        //You Get Error
                        if (result.Contains("-->"))
                        {
                            ((sqengine)game).Console.AddConsole(string.Format("Error on line: {0} command: {1}\nExiting script...", linecount, line.Trim()));
                            break;
                        }
                        else
                        {
                            //If Debug enalbed show me the script and the line number
                            if (((sqengine)game).isDebugEnabled)
                                ((sqengine)game).Console.AddConsole(string.Format("line: {0} command: {1}", linecount, line.Trim()));

                            ((sqengine)game).Console.AddConsole(result);
                        }
                    }
                }

            }
            else
            {

                return string.Format("File {0} not found!", command);
            }
            return "";

        }

        [ConsoleHelp("ls", "-- Display file in directory: Syntax ls c:\\ ", ConsoleCommandType.Normal)]
        public string ls(Game game, string command)
        {
            if (Directory.Exists(command))
            {
                string res = "";
                DirectoryInfo dinfo = new DirectoryInfo(command);
                FileInfo[] files = dinfo.GetFiles();
                res += string.Format(" Directory {0}\n", command);
                res += "Name:                     Size:\n";

                for (int i = 0; i < files.Count(); i++)
                {
                    res += string.Format("{0}                     {1}Mb\n", files[i].Name, files[i].Length);
                }

                return res;
            }
            return string.Format("Directory {0} not found", command);
        }
        [ConsoleHelp("dir", "-- Display file in directory: Syntax: dir c:\\ ", ConsoleCommandType.Normal)]
        public string dir(Game game, string command)
        {
            return ls(game, command);
        }

        [ConsoleHelp("mkdir", "-- Make a directory: Syntax: mkdir c:\\test ", ConsoleCommandType.Normal)]
        public string mkdir(Game game, string command)
        {
            try
            {
                Directory.CreateDirectory(command);
                return string.Format("Directory {0} created", command);
            }
            catch (Exception ex)
            {
                return string.Format("Error on create directory{0}\nError: {1}\nMessage{2}", command, ex.Message, ex.InnerException);
            }
        }

        [ConsoleHelp("addmessage", "-- Add message to queue: Syntax: addmessage 'text' 5(color) 3000(delay)", ConsoleCommandType.Normal)]
        public string addmessage(Game game, string command)
        {
            int i_pos = command.IndexOf("\"");
            int e_pos = command.IndexOf("\"", i_pos + 1);
            string msg = "";

            if (i_pos > -1 && e_pos > -1)
            {
                msg = command.Substring(i_pos, e_pos - i_pos + 1);
                command = command.Remove(i_pos, e_pos - i_pos + 1);
                msg = msg.Remove(i_pos, 1);
                msg = msg.Remove(msg.Length - 1, 1);

                command = command.TrimStart();

                string[] parms = command.Split(' ');

                if (parms.Length == 2)
                {
                    int color = 0;
                    int delay = 3000;

                    int.TryParse(parms[0], out color);
                    int.TryParse(parms[1], out delay);
                    ((sqengine)game).AddMessage(msg, Functions.colors[color], delay, "");
                    return "Message added";
                }
                else
                {

                    return string.Format("Error on {0}", command);
                }
            }
            else
            {
                return string.Format("Error on {0}", command);
            }

        }

        [ConsoleHelp("console_close", "-- Close console", ConsoleCommandType.Normal)]
        public string console_close(Game game, string command)
        {
            ((sqengine)game).Console.Disable();
            return "";
        }
        [ConsoleHelp("sleep", "-- Sleep console for milliseconds. Syntax: sleep 2000 (2sec)", ConsoleCommandType.Debug)]
        public string sleep(Game game, string command)
        {
            if (command != "")
            {
                if (Char.IsNumber(command, 0))
                {
                    Thread.Sleep(int.Parse(command));
                    return "";
                }
                else
                {
                    return string.Format("No valid input {0}", command);
                }

            }
            else
            {
                return "No input";
            }

        }
        [ConsoleHelp("load_intro", "-- Load intro file: Syntax: load_intro c:\test.intro", ConsoleCommandType.Normal)]
        public string load_intro(Game game, string command)
        {
            if (File.Exists(command))
            {
                ((sqengine)game).LoadIntro(true, command);
                return string.Format("Intro {0} loaded", command);

            }
            else
            {
                return string.Format("Intro {0} not found", command);
            }

        }
        [ConsoleHelp("gc_clean", "-- Call garbage collector", ConsoleCommandType.Debug)]
        public string gc_clean(Game game, string command)
        {
            long before_gc = GC.GetTotalMemory(true);
            GC.Collect();
            long after_gc = GC.GetTotalMemory(true);

            return string.Format("Garbage Collector excuted\nMemory before GC:{0}\nMemory after GC:{1}", Functions.ConvertBytesToMegabytes(before_gc), Functions.ConvertBytesToMegabytes(after_gc));

        }

        [ConsoleHelp("save_help", "-- Save the list of commands to file: Syntax: save_help c:\\commandlist.txt", ConsoleCommandType.Normal)]
        public string save_help(Game game, string command)
        {
            try
            {
                StreamWriter st = new StreamWriter(command);
                string[] help = GetCommandHelp("").Split('\n');
                for (int i = 0; i < help.Length; i++)
                {
                    st.WriteLine(help[i]);
                }
                st.Close();
                return string.Format("Command list save to {0}", command);
            }
            catch
            {
                return string.Format("Error during save file {0}", command);
            }
        }


        [ConsoleHelp("setskydome_theta", "-- Set Theta value of current skydome", ConsoleCommandType.Debug)]
        public string setskydome_theta(Game game, string command)
        {
            if (command != "")
            {
                float _theta = float.Parse(getskydome_theta(game, command));
                float.TryParse(command, out _theta);
                ((sqengine)game).CurrentSkydome.Theta = _theta;

                return "Theta set";

            }
            else
            {
                return "Value cannot be empty";
            }

        }


        [ConsoleHelp("getskydome_theta", "-- Get value of theta skydome", ConsoleCommandType.Debug)]
        public string getskydome_theta(Game game, string command)
        {
            return ((sqengine)game).CurrentSkydome.Theta.ToString();

        }

        [ConsoleHelp("setskydome_phi", "-- Set phi value of current skydome", ConsoleCommandType.Debug)]
        public string setskydome_phi(Game game, string command)
        {
            if (command != "")
            {
                float _phi = float.Parse(getskydome_phi(game, command));
                float.TryParse(command, out _phi);
                ((sqengine)game).CurrentSkydome.Phi = _phi;

                return "Phi set";

            }
            else
            {
                return "Value cannot be empty";

            }

        }

        [ConsoleHelp("getskydome_phi", "-- Get value of phi skydome", ConsoleCommandType.Debug)]
        public string getskydome_phi(Game game, string command)
        {
            return ((sqengine)game).CurrentSkydome.Phi.ToString();

        }

        [ConsoleHelp("twitter_statusupdate", "-- Send message to Twitter (?!): Syntax: twitter_statusupdate user pass \"message\" \nor set game var sq_twitter_user and sq_twitter_pass send_twitter \"message\" ", ConsoleCommandType.Normal)]
        public string twitter_statusupdate(Game game, string command)
        {

            InitTwitter(game);

            string message = "";
            string user = "";
            string password = "";
            int s_pos = 0;
            int e_pos = 0;

            if (command.Contains("\""))
            {
                s_pos = command.IndexOf("\"");
                e_pos = command.IndexOf("\"", s_pos + 1);

                if (s_pos != e_pos)
                {
                    message = command.Substring(s_pos, e_pos - s_pos);
                    command = command.Replace(message + "\"", string.Empty);

                    message = message.Replace("\"", string.Empty);

                    if (command.Split(' ').Length == 2)
                    {
                        user = command.Split(' ')[0];
                        password = command.Split(' ')[1];
                    }
                    else
                    {
                        user = ((sqengine)game).ConsoleGetVar(sqengine.VAR_SQTWITTER_USER);
                        password = ((sqengine)game).ConsoleGetVar(sqengine.VAR_SQTWITTER_PASSWORD);


                        if (user == "" || password == "")
                        {
                            return string.Format("{0} and/or {1} empty! ", sqengine.VAR_SQTWITTER_USER, sqengine.VAR_SQTWITTER_PASSWORD);
                        }
                        else
                        {
                            password = Functions.CheckPasswordString(password);

                            //OK we got :)

                        }
                    }

                }
                else
                {
                    return string.Format("{0} is not valid format", command);
                }


            }
            else
            {
                return help(game, "twitter_send");
            }

            if (user != "" && password != "" && message != "")
            {
                twitter.PrepareTwitterUpdate(user, password, message);
                return string.Format("Twitter message added to queue");
            }
            else
            {
                return string.Format("{0} is not valid format", command);
            }
        }


        [ConsoleHelp("twitter_enabledcheck", "-- Enable Twitter check for buddy friends, before use you must set sq_twitter_user and sq_twitter_passwd", ConsoleCommandType.Normal)]
        public string twitter_enabledcheck(Game game, string command)
        {
            InitTwitter(game);
            bool active = false;

            bool.TryParse(command, out active);

            string user = ((sqengine)game).ConsoleGetVar(sqengine.VAR_SQTWITTER_USER);
            string password = ((sqengine)game).ConsoleGetVar(sqengine.VAR_SQTWITTER_PASSWORD);

            if (user != "" && password != "")
            {
                password = Functions.CheckPasswordString(password);

                //300000 5 minutes
                twitter.PrepareTwitterCheckLoop(user, password, 300000, active);

                return string.Format("twitter_enabledcheck set to {0}", active);
            }
            else
            {
                return help(game, "twitter_enabledcheck");

            }

        }

        [ConsoleHelp("twitter_directmessages", "-- Check Twitter direct messages, before use you must set sq_twitter_user and sq_twitter_passwd", ConsoleCommandType.Normal)]
        public string twitter_directmessages(Game game, string command)
        {
            string user = ((sqengine)game).ConsoleGetVar(sqengine.VAR_SQTWITTER_USER);
            string password = ((sqengine)game).ConsoleGetVar(sqengine.VAR_SQTWITTER_PASSWORD);

            if (user != "" && password != "")
            {
                password = Functions.CheckPasswordString(password);

                InitTwitter(game);
                twitter.PrepareTwitterCheckDS(user, password);
            }
            else
            {
                help(game, "twitter_directmessages");
            }


            return "";
        }

        [ConsoleHelp("twitter_publictimeline", "-- Check Twitter direct messages, before use you must set sq_twitter_user and sq_twitter_passwd", ConsoleCommandType.Normal)]
        public string twitter_publictimeline(Game game, string command)
        {
            string user = ((sqengine)game).ConsoleGetVar(sqengine.VAR_SQTWITTER_USER);
            string password = ((sqengine)game).ConsoleGetVar(sqengine.VAR_SQTWITTER_PASSWORD);

            if (user != "" && password != "")
            {
                password = Functions.CheckPasswordString(password);
                InitTwitter(game);
                twitter.PrepareTwitterPTL(user, password);
            }
            else
            {
                help(game, "twitter_publictimeline");
            }


            return "";
        }

        [ConsoleHelp("twitter_replies", "-- Check Twitter replies messages, before use you must set sq_twitter_user and sq_twitter_passwd", ConsoleCommandType.Normal)]
        public string twitter_replies(Game game, string command)
        {
            string user = ((sqengine)game).ConsoleGetVar(sqengine.VAR_SQTWITTER_USER);
            string password = ((sqengine)game).ConsoleGetVar(sqengine.VAR_SQTWITTER_PASSWORD);

            if (user != "" && password != "")
            {
                password = Functions.CheckPasswordString(password);

                InitTwitter(game);
                twitter.PrepareTwitterGetReply(user, password);
            }
            else
            {
                help(game, "twitter_replies");
            }


            return "";
        }


        [ConsoleHelp("proxy_setup", "-- Enable proxy remote connections: Syntax: proxy_setup url:port username password", ConsoleCommandType.Normal)]
        public string proxy_setup(Game game, string command)
        {
            if (command.Split(' ').Length == 3)
            {
                string url = command.Split(' ')[0];
                string username = command.Split(' ')[1];
                string passwd = command.Split(' ')[2];


                if (!passwd.StartsWith("password:"))
                    passwd = "password:" + passwd;


                ((sqengine)game).ConsoleSetVar(sqengine.VAR_SQPROXY_ENABLED, true);
                ((sqengine)game).ConsoleSetVar(sqengine.VAR_SQPROXY_URL, url);
                ((sqengine)game).ConsoleSetVar(sqengine.VAR_SQPROXY_USER, username);
                ((sqengine)game).ConsoleSetVar(sqengine.VAR_SQPROXY_PASSWD, passwd);

                return "Proxy enabled";
            }
            else
            {

                return string.Format("Invalid format {0}", command);
            }
        }

        [ConsoleHelp("proxy_off", "-- Turnoff proxy and clean all", ConsoleCommandType.Normal)]
        public string proxy_off(Game game, string command)
        {
            ((sqengine)game).ConsoleSetVar(sqengine.VAR_SQPROXY_ENABLED, false);
            ((sqengine)game).ConsoleSetVar(sqengine.VAR_SQPROXY_URL, "");
            ((sqengine)game).ConsoleSetVar(sqengine.VAR_SQPROXY_USER, "");
            ((sqengine)game).ConsoleSetVar(sqengine.VAR_SQPROXY_PASSWD, "");

            return "Proxy off";
        }

        [ConsoleHelp("loadkeys", "-- Load keymap for console: Syntax: loadkeys keytable: Ex: loadkeys it (for italian) us (for usa)", ConsoleCommandType.Normal)]
        public string loadkeys(Game game, string command)
        {
            if (command != "")
            {
                bool result = ((sqengine)(game)).Console.RegisterValidKeys(command);

                if (result)
                {
                    return string.Format("Keytable {0} loaded", command);
                }
                else
                {
                    return string.Format("Keytable {0} Not found!", command);
                }
            }
            else
            {

                return help(game, "loadkeys");
            }
        }

        [ConsoleHelp("network_ext_ip", "-- Get External ip address: Syntax: network_ext_ip var (if var il null print the result)", ConsoleCommandType.Normal)]
        public string network_ext_ip(Game game, string command)
        {
            InitNetwork(game);
            networkapi.PrepareGetExternalIP(command);
            return string.Empty;

        }

        [ConsoleHelp("network_int_ip", "-- Get iternal ip address: Syntax: network_int_ip var (if var il null print the result)", ConsoleCommandType.Normal)]
        public string network_int_ip(Game game, string command)
        {
            InitNetwork(game);
            string int_ip = networkapi.GetInternalIp();
            if (string.IsNullOrEmpty(command))
                return int_ip;
            else
            {
                set(game, string.Format("{0} {1}", command, int_ip));
                return string.Empty;
            }

        }


        [ConsoleHelp("twitter_lobbysendsearch", "-- Send to twitter with lobby protocol game request. note you must set sq_twitter_user and sq_twitter_passwd", ConsoleCommandType.Experimental)]
        public string twitter_lobbysendsearch(Game game, string command)
        {

            InitTwitter(game);
            string tw_user = ((sqengine)game).ConsoleGetVar(sqengine.VAR_SQTWITTER_USER);
            string tw_pass = ((sqengine)game).ConsoleGetVar(sqengine.VAR_SQTWITTER_PASSWORD);


            tw_pass = Functions.CheckPasswordString(tw_pass);


            if (!string.IsNullOrEmpty(tw_user) && !string.IsNullOrEmpty(tw_pass))
            {
                string player_name = get(game, sqengine.VAR_SQPLAYER_NAME);
                string location = get(game, sqengine.VAR_SQPLAYER_LOCATION);
                network_ext_ip(game, sqengine.VAR_SQNETWORK_EXTIP);
                string ext_ip = get(game, sqengine.VAR_SQNETWORK_EXTIP);

                string broadcast_msg = Engine.Network.LobbyProtocol.ParsePacket(player_name, location, global::sqengine.Engine.Network.LobbyType.SearchForPlay, ext_ip, null);
                twitter.PrepareTwitterUpdate(tw_user, tw_pass, broadcast_msg);
                return string.Format("[Lobby] Send broadcast");
            }
            else
            {

                return help(game, "twitter_lobbysendsearch");
            }


        }



        private void InitTwitter(Game game)
        {
            if (twitter == null)
            {
                twitter = new TwitterAPI(game);
            }

        }

        private void InitNetwork(Game game)
        {
            if (networkapi == null)
            {
                networkapi = new NetworkAPI(game);

            }
        }
        [ConsoleHelp("navigate", "-- Navigate to url: ex: navigate http://www.libero.it visible {0 | 1}", ConsoleCommandType.Normal)]     
        public string navigate(Game game, string command)
        {
            string url = string.Empty;
            bool visible = true;

            if (!string.IsNullOrEmpty(command))
            {
                if (command.Split(' ').Length > 1)
                {
                    url = command.Split(' ')[0];
                    if (command.Split(' ')[1] == "1")
                        visible = true;
                    else
                        visible = false;
                }
                else
                {
                    url = command.Split(' ')[0];
                }
                
                ((sqengine)game).WebBrowserNavigate(url,visible);
                
                return string.Empty;
            }
            else
            {
                return help(game, "navigate");
            }
        }

        /// <summary>
        /// Parse string if you want replace variable Ex: echo my ip address is %{sq_ext_ip}
        /// </summary>
        /// <param name="game"></param>
        /// <param name="text">text if you want parse, normally is on echo</param>
        /// <returns>parsed string</returns>
        public string ParseVarString(Game game, string text)
        {

            if (text.IndexOf("%{") > -1)
            {
                int pos_i = -1;
                int pos_e = -1;
                string con_var = "";

                pos_i = text.IndexOf("%{");
                pos_e = text.IndexOf("}", pos_i);
                con_var = text.Substring(pos_i, pos_e - pos_i + 1);

                //%{aa}
                string var_value = con_var.Replace("%{", string.Empty).Replace("}", string.Empty);
                var_value = get(game, var_value);

                if (!var_value.Contains("not found"))
                {

                    text = text.Replace(con_var, var_value);
                }
                else
                {
                    text = text.Replace(con_var, string.Empty);
                }

                return ParseVarString(game, text);
            }

            return text;

        }

        /// <summary>
        /// Parse string replacing with command result Ex: set version_of ^{version}
        /// </summary>
        /// <param name="game">Current game</param>
        /// <param name="text">Text to parse</param>
        /// <returns>Parsed string</returns>
        public string ParseCmdString(Game game, string text)
        {
            if (text.IndexOf("@{") > -1)
            {
                int pos_i = -1;
                int pos_e = -1;
                string con_var = "";

                pos_i = text.IndexOf("@{");
                pos_e = text.IndexOf("}", pos_i);
                con_var = text.Substring(pos_i, pos_e - pos_i + 1);

                string var_value = con_var.Replace("@{", string.Empty).Replace("}", string.Empty);
                var_value = ((sqengine)game).Console.ExecCommand(var_value);
                if (var_value.Contains("ERROR"))
                    var_value = "{error}";

                text = text.Replace(con_var, var_value);


                return ParseCmdString(game, text);
            }

            return text;
        }


        

        private string GetCommandsHelpClass(string command)
        {

            Type type = typeof(ConsoleCommands);
            ConsoleHelpAttribute HelpAttr;
            string help_str = "";

            

            foreach (MethodInfo method in type.GetMethods())
            {
                foreach (Attribute attr in method.GetCustomAttributes(true))
                {
                    HelpAttr = attr as ConsoleHelpAttribute;

                    if (null != HelpAttr)
                    {
                        

                        if (command == "")
                        {
                            _dict.Add(HelpAttr.Command, HelpAttr.Help);
                        }
                        else
                        {
                            if (command == HelpAttr.Command)
                            {
                                help_str = string.Format("{0} {1} [{2}]", HelpAttr.Command, HelpAttr.Help, HelpAttr.CommandType.ToString());
                            }

                        }
                    }
                }

            }

            if (command == "")
            {
                help_str = GetAllHelpCommand();

            }
            return help_str;

        }

        private string GetAllHelpCommand()
        {
            string help_str = "";

            _sorted = new SortedDictionary<string, string>(_dict);

            foreach (KeyValuePair<string, string> itm in _sorted)
            {
                help_str += string.Format("{0} {1}\n", itm.Key, itm.Value);

            }

            return help_str;

        }

        public string GetCommandHelp(string command)
        {
            if (_dict.Count == 0)
            {
                return GetCommandsHelpClass(command);
            }
            else
            {
                if (command != "")
                    return _dict[command];
                else
                    return GetAllHelpCommand();

            }
      
        }

        public Dictionary<string, string> GetCommandsHelp()
        {
            Type type = typeof(ConsoleCommands);
            ConsoleHelpAttribute HelpAttr;

            if (_tmpdic.Count == 0)
            {
                foreach (MethodInfo method in type.GetMethods())
                {
                    foreach (Attribute attr in method.GetCustomAttributes(true))
                    {
                        HelpAttr = attr as ConsoleHelpAttribute;
                        if (null != HelpAttr)
                        {
                            _tmpdic.Add(HelpAttr.Command, HelpAttr.Help);
                        }
                    }

                }
            }

            SortedDictionary<string, string> sorted_cmds = new SortedDictionary<string, string>(_tmpdic);
            return new Dictionary<string, string>(sorted_cmds);

        }

    }
}
